// ActionScript file
package
{
	import com.lipi.excel.Excel;
	
	import events.ParaEvent;
	
	import flash.desktop.NativeProcess;
	import flash.desktop.NativeProcessStartupInfo;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.TimerEvent;
	import flash.filesystem.File;
	import flash.net.FileFilter;
	import flash.utils.ByteArray;
	import flash.utils.Timer;
	import flash.utils.setTimeout;
	
	import mx.controls.Alert;
	
	import org.osmf.events.TimeEvent;
	
	import source.JsonObj;
	
	import utils.EasyFile;
	import utils.FileProxy;
	import utils.FilesLoader;
	import utils.FilesLoaderEvent;
	/**
	 * 源文件分离器
	 * @author Roland
	 *
	 */
	public class SourceFilesSeparaterBasic extends EventDispatcher
	{

		public static const SEPARATED:String = "separated";

		public static const SEPARATING:String = "separating";
		
		protected static var _instance:SourceFilesSeparaterBasic;

		public static function getInstance():SourceFilesSeparaterBasic
		{
			if (!_instance)
				_instance = new SourceFilesSeparaterBasic();

			return _instance;
		}

		public var errors:Array;

		protected var _dataModel:DataModelBasic;

		protected var _lang:String;

		protected var configDir:File;

		protected var configFiles:Array;

		protected var matsDir:File;

		protected var matsFiles:Array;

		protected var needSep:Boolean = true; //是否需要拆分

		protected var _xlsFilterFun:Function;
		
		protected var _matsFilterFun:Function;
		/**
		 *	开始分离文件
		 * @param xlsPath 配置表目录
		 * @param matsPath 外部素材目录
		 * @param lang 语言版本,如:"_xn"
		 * @param dataModel 分离出的文件要储存到的数据层dataModel
		 *	@param xlsFilterFun [可选]形式为f(file:File):Boolean{}的函数,将只处理xlsPath目录下的,f函数返回为true的文件
		 * @param matsFilterFun [可选]形式为f(file:File):Boolean{}的函数,将只处理matsPath目录下的,f函数返回为true的素材文件
		 */
		public function start(xlsPath:String, matsPath:String, lang:String, dataModel:DataModelBasic,xlsFilterFun:Function = null,matsFilterFun:Function = null):void
		{
			_dataModel = dataModel;
			_lang = lang;
			_xlsFilterFun = xlsFilterFun;
			_matsFilterFun = matsFilterFun;
			
			errors = new Array();

			configDir = new File(xlsPath);

			if (!configDir.exists)
			{
				errors.push("配置表文件夹不存在");

				dispatchEvent(new ParaEvent(SEPARATED, "配置表文件夹不存在"));

				return;
			}

			matsDir = new File(matsPath);

			if (!matsDir.exists)
			{
				errors.push("素材文件夹不存在");

				dispatchEvent(new ParaEvent(SEPARATED, "配置表文件夹不存在"));

				return;
			}


			configFiles = FileProxy.getTypicalFileList(configDir, new FileFilter("", "*.xlsx;*.json"));
			configFiles = dealFileFilterFun(configFiles,_xlsFilterFun);
			
			var timer:Timer = new Timer(300);
			timer.addEventListener(TimerEvent.TIMER, singleTask);
			timer.start();

			var msg:String = "正在处理: " + configFiles[0].name;
			dispatchEvent(new ParaEvent(SEPARATING, msg));
		}

		/**
		 *	根据给入的filterFun过滤fileList文件数组
		 * @param fileList
		 * @param filterFun
		 * @return 过滤后的数组,不会改变fileList
		 * 
		 */
		private function dealFileFilterFun(fileList:Array,filterFun:Function):Array
		{
			var newList:Array = [];
			if(filterFun!=null)
			{
				for(var i:int = 0;i<fileList.length;i++)
				{
					var file:File = fileList[i] as File;
					if(file && filterFun(file) == true)
					{
						newList.push(file);
					}
				}
			}else{
				newList = fileList;
			}
			return newList;
		}
		
		protected function dealSingleExcelFile(file:File):Array
		{
			var $errors:Array = new Array();

			if (file.type != ".xlsx")
			{
				if (file.type != ".svn")
					$errors.push("error: " + file.name + "不是xlsx或者svn文件");

				return $errors;
			}

			var ba:ByteArray = EasyFile.loadByteArryData(file.url);
			var excel:Excel = new Excel(ba);
			var excelName:String = file.name.split(".")[0];
			if (needSep)
			{

				var firstSheetName:String = excel.getSheetName();
				var curruntSheetName:String;
				for (var sheetIndex:int = 0; sheetIndex < 99; sheetIndex++)
				{
					curruntSheetName = excel.getSheetName(sheetIndex);
					if (curruntSheetName == "All" || curruntSheetName == (excelName + _lang) || curruntSheetName == "Sheet1")
					{
						var error:String = excel.setFirstSheet(curruntSheetName);
						if (error == "")
						{
							firstSheetName = curruntSheetName;
							break;
						}
						else
						{
							$errors.push(error);
						}
					}
				}
				var firstSheetNameArr:Array = firstSheetName.split("_");

				if (firstSheetNameArr[0] == "All") //单表分离
				{
					var defaultLan:String = firstSheetNameArr[1];

					var nowLan:String = _lang.substr(1); //忽略前面的"_"

					if (nowLan != defaultLan)
					{
						var sheetArray:Array = excel.getSheetArray();

						var titleRow:Array = sheetArray[JsonObj.INDEX_ROW];

						if (!titleRow)
						{
							$errors.push("error: " + file.name + " is empty");

							return $errors;
						}

						var copyList:Array = new Array();

						var titleDic:Object = new Object();

						for (var i:int = 0; i < titleRow.length; i++)
						{
							if (!titleRow[i])
								continue;
							titleDic[titleRow[i]] = i;
						}

						for (i = 0; i < titleRow.length; i++)
						{
							if (!titleRow[i])
								continue;

							var titleArr:Array = titleRow[i].split("_");

							if (titleArr.pop() == nowLan)
							{
								var oriTitle:String = titleArr.join("_");

								if (titleDic[oriTitle] != null)
								{
									var copyTask:Object = { from: i, to: titleDic[titleArr.join("_")]};
									copyList.push(copyTask);
								}
								else
								{
									$errors.push("error: " + file.name + "->" + oriTitle + " not found");
								}
							}
						}

						for (i = 0; i < copyList.length; i++)
							excel.copyCol(0, copyList[i]["from"], copyList[i]["to"], [ 0, 1 ]);
					}

					saveToDataModel(excelName, excel);
				}
				else if (firstSheetNameArr[0] == "Sheet1") //不分离
				{
					saveToDataModel(excelName, excel);
				}
				else //多表单分离
				{
					saveToDataModel(excelName, excel);
				}
			}
			else
			{
				saveToDataModel(excelName, excel);
			}

			return $errors;
		}

		protected function dealSingleJsonFile(file:File):Array
		{
			var $errors:Array = new Array();

			if (file.type != ".json")
			{
				if (file.type != ".svn")
					$errors.push("error: " + file.name + "不是json或者svn文件");
				return $errors;
			}

			var jsonStr:String = EasyFile.loadStringData(file.url);
			saveToDataModel(file.name.split(".")[0], jsonStr);
			return $errors;
		}

		/**
		 *	保存数据到DataModel
		 * @param fileName 文件名
		 * @param data 文件数据,只支持Excel和Json字符串两种类型数据
		 *
		 */
		protected function saveToDataModel(fileName:String, data:*):void
		{
			if (data is Excel)
			{
				_dataModel.addExcel(fileName, data as Excel);
			}
			else if (data is String)
			{
				_dataModel.addJson(fileName, data as String);
			}
			else
			{
				errors.push("error:" + fileName + "无法识别的数据格式");
			}
		}

		protected function singleTask(event:TimerEvent):void
		{
			if (!configFiles)
				return;

			if (configFiles.length > 0) //处理配置文件------------------------------------------
			{
				var singleConfigFile:File = configFiles[0] as File;
				var subErrors:Array = [];
				if (singleConfigFile.type == ".xlsx")
				{
					subErrors = dealSingleExcelFile(singleConfigFile);
				}
				else if (singleConfigFile.type == ".json")
				{
					subErrors = dealSingleJsonFile(singleConfigFile);
				}
				else
				{
					errors.push("error:" + singleConfigFile.name + "意外的文件格式");
				}

				if (subErrors.length > 0)
					errors = errors.concat(subErrors);

				configFiles.shift();

				var msg:String;
				if (configFiles.length > 0)
					msg = "正在读取: \n" + configFiles[0].name;
				else
					msg = "正在处理素材文件";

				dispatchEvent(new ParaEvent(SEPARATING, msg));
			}
			else //处理素材文件------------------------------------------
			{
				event.target.stop();
				event.target.removeEventListener(TimerEvent.TIMER, singleTask);


				var paraEvent:ParaEvent;
				//素材文件
				var matsfileArr:Array = FileProxy.getTypicalFileList(matsDir, new FileFilter("", "*.swf;*.png;*.jpg;*.mp3;*.wma"));
				//地图文件
				var mapFileArr:Array = FileProxy.getTypicalFileList(configDir, new FileFilter("", "*.psc"));
				var fileArr:Array = matsfileArr.concat(mapFileArr);
				fileArr = dealFileFilterFun(fileArr,_matsFilterFun);
				
				var timer:Timer = new Timer(1, fileArr.length);
				var index:int = 0;
				if(fileArr.length>0)
				{
					timer.start();
				}else{
					onComplete(null);
				}
				
				timer.addEventListener(TimerEvent.TIMER, function(e:TimerEvent):void
				{
					var file:File = fileArr[index] as File;
					var fileName:String = file.name.split(".")[0];
					if (file.type == ".swf")
					{
						_dataModel.addSwfFile(fileName, file);
						paraEvent = new ParaEvent(SEPARATING, "扫描素材文件:\n" + file.name);
					}
					else
					{
						var data:ByteArray = EasyFile.loadByteArryData(file.url);
						_dataModel.addOther(fileName, file.type, data);
						paraEvent = new ParaEvent(SEPARATING, "读取外部文件:\n" + file.name);
					}
					paraEvent.progress = new ProgressEvent("已处理", false, false, index, fileArr.length);
					dispatchEvent(paraEvent);
					index++;
				});
				timer.addEventListener(TimerEvent.TIMER_COMPLETE,onComplete);
				function onComplete(e:TimerEvent):void
				{
					timer.removeEventListener(TimerEvent.TIMER_COMPLETE,onComplete);
					trace("complete");
					matsFiles = fileArr;
					paraEvent = new ParaEvent(SEPARATED, "完成");
					paraEvent.progress = new ProgressEvent("扫描完成", false, false, 100, 100);
					dispatchEvent(paraEvent);
				}
			}
		}
	}
}
